home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / rhythmbox / plugins / magnatune / __init__.py next >
Encoding:
Python Source  |  2009-04-07  |  10.8 KB  |  295 lines

  1. # -*- Mode: python; coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*-
  2. #
  3. # Copyright (C) 2006 Adam Zimmerman  <adam_zimmerman@sfu.ca>
  4. # Copyright (C) 2006 James Livingston  <doclivingston@gmail.com>
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2, or (at your option)
  9. # any later version.
  10. #
  11. # The Rhythmbox authors hereby grant permission for non-GPL compatible
  12. # GStreamer plugins to be used and distributed together with GStreamer
  13. # and Rhythmbox. This permission is above and beyond the permissions granted
  14. # by the GPL license by which Rhythmbox is covered. If you modify this code
  15. # you may extend this exception to your version of the code, but you are not
  16. # obligated to do so. If you do not wish to do so, delete this exception
  17. # statement from your version.
  18. #
  19. # This program is distributed in the hope that it will be useful,
  20. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. # GNU General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License
  25. # along with this program; if not, write to the Free Software
  26. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
  27.  
  28. import rhythmdb, rb
  29. import gobject
  30. import gtk, gtk.glade
  31. import gconf, gnome
  32.  
  33. import urllib
  34. import zipfile
  35. import sys, os.path
  36. import xml
  37. import datetime
  38. import string
  39.  
  40. from MagnatuneSource import MagnatuneSource
  41.  
  42. has_gnome_keyring = False
  43. #try:
  44. #    import gnomekeyring
  45. #    has_gnome_keyring = True
  46. #except:
  47. #    pass    
  48.  
  49. popup_ui = """
  50. <ui>
  51.   <popup name="MagnatuneSourceViewPopup">
  52.     <menuitem name="AddToQueueLibraryPopup" action="AddToQueue"/>
  53.     <menuitem name="MagnatunePurchaseAlbum" action="MagnatunePurchaseAlbum"/>
  54.     <menuitem name="MagnatunePurchaseCD" action="MagnatunePurchaseCD"/>
  55.     <menuitem name="MagnatuneArtistInfo" action="MagnatuneArtistInfo"/>
  56.     <menuitem name="MagnatuneCancelDownload" action="MagnatuneCancelDownload"/>
  57.     <separator/>
  58.     <menuitem name="BrowseGenreLibraryPopup" action="BrowserSrcChooseGenre"/>
  59.     <menuitem name="BrowseArtistLibraryPopup" action="BrowserSrcChooseArtist"/>
  60.     <menuitem name="BrowseAlbumLibraryPopup" action="BrowserSrcChooseAlbum"/>
  61.     <separator/>
  62.     <menuitem name="PropertiesLibraryPopup" action="MusicProperties"/>
  63.   </popup>
  64. </ui>
  65. """
  66.  
  67. keyring_attributes = {"name": "rb-magnatune-cc-data"}
  68.  
  69. class Magnatune(rb.Plugin):
  70.     client = gconf.client_get_default()
  71.  
  72.     format_list = ['ogg', 'flac', 'wav', 'mp3-vbr', 'mp3-cbr']
  73.  
  74.     gconf_keys = {
  75.         'format': "/apps/rhythmbox/plugins/magnatune/format",
  76.         'pay': "/apps/rhythmbox/plugins/magnatune/pay",
  77.         'ccauthtoken': "/apps/rhythmbox/plugins/magnatune/ccauthtoken"
  78.     }
  79.  
  80.  
  81.     #
  82.     # Core methods
  83.     #
  84.     
  85.     def __init__(self):
  86.         rb.Plugin.__init__(self)
  87.  
  88.     def activate(self, shell):
  89.         self.shell = shell # so the source can update the progress bar
  90.         self.db = shell.get_property("db")
  91.         self.keyring = None
  92.  
  93.         group = rb.rb_source_group_get_by_name ("stores")
  94.          if not group:
  95.              group = rb.rb_source_group_register ("stores",
  96.                                   _("Stores"),
  97.                                   rb.SOURCE_GROUP_CATEGORY_FIXED)
  98.  
  99.         self.entry_type = self.db.entry_register_type("MagnatuneEntryType")
  100.         # allow changes which don't do anything
  101.         self.entry_type.can_sync_metadata = True
  102.         self.entry_type.sync_metadata = None
  103.  
  104.         theme = gtk.icon_theme_get_default()
  105.         rb.append_plugin_source_path(theme, "/icons")
  106.  
  107.         width, height = gtk.icon_size_lookup(gtk.ICON_SIZE_LARGE_TOOLBAR)
  108.         icon = rb.try_load_icon(theme, "magnatune", width, 0)
  109.  
  110.         self.source = gobject.new (MagnatuneSource,
  111.                         shell=shell,
  112.                         entry_type=self.entry_type,
  113.                         source_group=group,
  114.                        icon=icon,
  115.                         plugin=self)
  116.  
  117.         shell.register_entry_type_for_source(self.source, self.entry_type)
  118.         shell.append_source(self.source, None) # Add the source to the list
  119.         
  120.         manager = shell.get_player().get_property('ui-manager')
  121.         # Add the popup menu actions
  122.         action = gtk.Action('MagnatunePurchaseAlbum', _('Purchase Album'),
  123.                 _("Purchase this album from Magnatune"),
  124.                 'gtk-save')
  125.         action.connect('activate', lambda a: self.shell.get_property("selected-source").purchase_album())
  126.         self.action_group = gtk.ActionGroup('MagnatunePluginActions')
  127.         self.action_group.add_action(action)
  128.         action = gtk.Action('MagnatunePurchaseCD', _('Purchase Physical CD'),
  129.                 _("Purchase a physical CD from Magnatune"),
  130.                 'gtk-cdrom')
  131.         action.connect('activate', lambda a: self.shell.get_property("selected-source").buy_cd())
  132.         self.action_group.add_action(action)
  133.         action = gtk.Action('MagnatuneArtistInfo', _('Artist Information'),
  134.                 _("Get information about this artist"),
  135.                 'gtk-info')
  136.         action.connect('activate', lambda a: self.shell.get_property("selected-source").display_artist_info())
  137.         self.action_group.add_action(action)
  138.         action = gtk.Action('MagnatuneCancelDownload', _('Cancel Downloads'),
  139.                 _("Stop downloading purchased albums"),
  140.                 'gtk-stop')
  141.         action.connect('activate', lambda a: self.shell.get_property("selected-source").cancel_downloads())
  142.         action.set_sensitive(False)
  143.         self.action_group.add_action(action)
  144.         
  145.         manager.insert_action_group(self.action_group, 0)
  146.         self.ui_id = manager.add_ui_from_string(popup_ui)
  147.  
  148.         self.pec_id = shell.get_player().connect('playing-song-changed', self.playing_entry_changed)
  149.         manager.ensure_update()
  150.  
  151.     def deactivate(self, shell):
  152.         manager = shell.get_player().get_property('ui-manager')
  153.         manager.remove_ui (self.ui_id)
  154.         manager.remove_action_group(self.action_group)
  155.         self.action_group = None
  156.  
  157.         shell.get_player().disconnect (self.pec_id)
  158.  
  159.         self.db.entry_delete_by_type(self.entry_type)
  160.         self.db.commit()
  161.         self.db = None
  162.         self.entry_type = None
  163.         self.source.delete_thyself()
  164.         self.source = None
  165.         self.shell = None
  166.         self.keyring = None
  167.  
  168.     def playing_entry_changed (self, sp, entry):
  169.         self.source.playing_entry_changed (entry)
  170.  
  171.     def get_keyring(self):
  172.         if self.keyring is None:
  173.             self.keyring = gnomekeyring.get_default_keyring_sync()
  174.         return self.keyring
  175.  
  176.     def store_cc_details(self, *details):
  177.         if has_gnome_keyring:
  178.             print "storing CC details"
  179.             try:
  180.                 id = gnomekeyring.item_create_sync(self.get_keyring(),
  181.                         gnomekeyring.ITEM_GENERIC_SECRET,
  182.                         "Magnatune credit card info", keyring_attributes,
  183.                         string.join (details, '\n'), True)
  184.             except Exception, e:
  185.                 print e
  186.  
  187.     def clear_cc_details(self):
  188.         if has_gnome_keyring:
  189.             print "clearing CC details"
  190.             try:
  191.                 ids = gnomekeyring.find_items_sync (gnomekeyring.ITEM_GENERIC_SECRET, keyring_attributes)
  192.                 gnomekeyring.item_delete_sync (self.get_keyring(), id[0])
  193.             except Exception, e:
  194.                 print e
  195.     
  196.     def get_cc_details(self):
  197.         if has_gnome_keyring:
  198.             print "getting CC details"
  199.             try:
  200.                 ids = gnomekeyring.find_items_sync (gnomekeyring.ITEM_GENERIC_SECRET, keyring_attributes)
  201.                 data =  gnomekeyring.item_get_info_sync(self.get_keyring(), ids[0]).get_secret()
  202.                 return string.split(data, "\n")
  203.             except Exception, e:
  204.                 print e
  205.         return ("", "", 0, "", "")
  206.     
  207.     def create_configure_dialog(self, dialog=None):
  208.         if dialog == None:
  209.             def fill_cc_details():
  210.                 try:
  211.                     (ccnumber, ccyear, ccmonth, name, email) = self.get_cc_details()
  212.                     gladexml.get_widget("cc_entry").set_text(ccnumber)
  213.                     gladexml.get_widget("yy_entry").set_text(ccyear)
  214.                     gladexml.get_widget("mm_entry").set_active(int(ccmonth)-1)
  215.                     gladexml.get_widget("name_entry").set_text(name)
  216.                     gladexml.get_widget("email_entry").set_text(email)
  217.                     gladexml.get_widget("remember_cc_details").set_active(True)
  218.                 except Exception, e:
  219.                     print e
  220.  
  221.                     gladexml.get_widget("cc_entry").set_text("")
  222.                     gladexml.get_widget("yy_entry").set_text("")
  223.                     gladexml.get_widget("mm_entry").set_active(0)
  224.                     gladexml.get_widget("name_entry").set_text("")
  225.                     gladexml.get_widget("email_entry").set_text("")
  226.                     gladexml.get_widget("remember_cc_details").set_active(False)
  227.  
  228.             def update_expired():
  229.                 mm = gladexml.get_widget("mm_entry").get_active() + 1
  230.                 yy = 0
  231.                 try:
  232.                     yy = int(gladexml.get_widget("yy_entry").get_text())
  233.                 except Exception, e:
  234.                     print e
  235.                     gladexml.get_widget("cc_expired_label").hide()
  236.                     return
  237.  
  238.                 if yy < (datetime.date.today().year % 100):
  239.                     gladexml.get_widget("cc_expired_label").show()
  240.                 elif (yy == (datetime.date.today().year % 100) and mm < datetime.date.today().month):
  241.                     gladexml.get_widget("cc_expired_label").show()
  242.                 else:
  243.                     gladexml.get_widget("cc_expired_label").hide()
  244.             
  245.             def remember_checkbox_toggled (button):
  246.                 print "remember CC details toggled " + str(button.get_active())
  247.                 gladexml.get_widget("cc_entry").set_sensitive(button.get_active())
  248.                 gladexml.get_widget("mm_entry").set_sensitive(button.get_active())
  249.                 gladexml.get_widget("yy_entry").set_sensitive(button.get_active())
  250.                 gladexml.get_widget("name_entry").set_sensitive(button.get_active())
  251.                 gladexml.get_widget("email_entry").set_sensitive(button.get_active())
  252.  
  253.                 if not button.get_active():
  254.                     try:
  255.                         self.clear_cc_details ()
  256.                     except Exception, e:
  257.                         print e
  258. #                fill_cc_details()
  259.  
  260.  
  261.             self.configure_callback_dic = {
  262. #                "rb_magnatune_yy_entry_changed_cb" : lambda w: update_expired(),
  263. #                "rb_magnatune_mm_entry_changed_cb" : lambda w: update_expired(),
  264. #                "rb_magnatune_name_entry_changed_cb" : lambda w: None,
  265. #                "rb_magnatune_cc_entry_changed_cb" : lambda w: None,
  266. #                "rb_magnatune_email_entry_changed_cb" : lambda w: None,
  267.                 "rb_magnatune_pay_combobox_changed_cb" : lambda w: self.client.set_int(self.gconf_keys['pay'], w.get_active() + 5),
  268.                 "rb_magnatune_audio_combobox_changed_cb" : lambda w: self.client.set_string(self.gconf_keys['format'], self.format_list[w.get_active()]),
  269.                 "rb_magnatune_remember_cc_details_toggled_cb" : remember_checkbox_toggled
  270.             }
  271.  
  272.             gladexml = gtk.glade.XML(self.find_file("magnatune-prefs.glade"))
  273.             gladexml.signal_autoconnect(self.configure_callback_dic)
  274.  
  275.             # FIXME this bit should be in glade too
  276.             dialog = gladexml.get_widget('preferences_dialog')
  277.             def dialog_response (dialog, response):
  278.                 if gladexml.get_widget("remember_cc_details").get_active():
  279.                     ccnumber = gladexml.get_widget("cc_entry").get_text()
  280.                     ccyear = gladexml.get_widget("yy_entry").get_text()
  281.                     ccmonth = str(gladexml.get_widget("mm_entry").get_active() + 1)
  282.                     name = gladexml.get_widget("name_entry").get_text()
  283.                     email = gladexml.get_widget("email_entry").get_text()
  284.                     self.store_cc_details(ccnumber, ccyear, ccmonth, name, email)
  285.                 dialog.hide()
  286.             dialog.connect("response", dialog_response)
  287.             
  288.             gladexml.get_widget("cc_details_box").props.visible = has_gnome_keyring
  289.             gladexml.get_widget("pay_combobox").set_active(self.client.get_int(self.gconf_keys['pay']) - 5)
  290.             gladexml.get_widget("audio_combobox").set_active(self.format_list.index(self.client.get_string(self.gconf_keys['format'])))
  291.             fill_cc_details()
  292.  
  293.         dialog.present()
  294.         return dialog
  295.